package com.banmao;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.ZipUtil;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Data
@Slf4j
@Builder
public class XManChapter implements Runnable {

    private String baseDirPath;

    private File chapterFile;

    //private String comicName;

    //private String comicCode;

    private String chapterTitle;

    private String chapterCode;

    private Integer pages;

    private HashMap<String, String> cookies;

    private CountDownLatch chapter_countDownLatch;

    private AtomicBoolean chapterSuccess;

    private Integer indexInMap;

    private void init() {
        this.baseDirPath = System.getProperty("user.dir") + File.separator +
                this.baseDirPath + File.separator + XManhua.comicName + File.separator + this.chapterTitle;
        this.chapterFile = FileUtil.mkdir(this.baseDirPath);
    }

    //private static XManhua.XManhuaFile prepareDownloadDir(String comicCode, String chapterName) {
    //    XManhua.XManhuaFile xManhuaFile = XManhua.XManhuaFile.builder()
    //            .comicName(X_MANHUA_TITLE_THREAD_LOCAL.get() == null
    //                    ? comicCode : X_MANHUA_TITLE_THREAD_LOCAL.get())
    //            .chapterName(chapterName)
    //            .baseDir("static").build();
    //    xManhuaFile.init();
    //    return xManhuaFile;
    //}

    public void getChapterCookies() {
        FakeBrowser fakeBrowser = FakeBrowser.builder()
                .host(Constant.HOST)
                .headers(Constant.BASE_HEADERS)
                .build();
        fakeBrowser.addHeader("referer", "https://" + Constant.HOST + "/" + chapterCode);
        String html = fakeBrowser.sendGet(chapterCode, null);
        this.cookies = findCookies(html);
    }

    public static HashMap<String, String> findCookies(String html) {
        Elements script = Jsoup.parse(html).getElementsByTag("script");
        HashMap<String, String> cookies = new HashMap<>();
        for (Element element : script) {
            String html1 = element.html();
            List<String> key = ReUtil.findAll("var\\s{1,3}(.*?)=(.*?);", html1, 1);
            List<String> value = ReUtil.findAll("var\\s{1,3}(.*?)=(.*?);", html1, 2);
            Iterator<String> keyIterator = key.iterator();
            Iterator<String> valIterator = value.iterator();
            while (keyIterator.hasNext() && valIterator.hasNext()) {
                cookies.put(keyIterator.next(), valIterator.next().replace("\"", ""));
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("cookies:{}", cookies);
        }
        return cookies;
    }

    @Override
    public void run() {
        init();

        getChapterCookies();
        String xmanhua_image_count = cookies.get("XMANHUA_IMAGE_COUNT");
        this.pages = Integer.parseInt(xmanhua_image_count);

        chapter_countDownLatch = new CountDownLatch(this.pages);

        ThreadPoolExecutor threadPool = ExecutorBuilder.create()
                .setCorePoolSize(pages / 5)
                .setMaxPoolSize(pages / 2)
                .setKeepAliveTime(10, TimeUnit.SECONDS)
                .useArrayBlockingQueue(pages)
                .build();

        for (int pageIndex = 1; pageIndex <= pages; pageIndex++) {
            XManPage xManPage = XManPage.builder()
                    .xManChapter(this)
                    .pageIndex(pageIndex)
                    .build();
            threadPool.execute(xManPage);
        }

        try {
            chapter_countDownLatch.await();
            threadPool.shutdown();

            ZipUtil.zip(chapterFile);
            log.info("{} 已压缩", chapterFile.getName());
        } catch (Exception e) {
            //throw new RuntimeException(e);
        } finally {
            XManhua.XMAN_COUNTDOWNLATCH.countDown();
        }

    }
}
